package de.karlNet.sambamanager.ldapController.commands.macros;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import javax.naming.NamingException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Controller;

import de.karlNet.sambamanager.ldapController.LdapMemberOfTree;
import de.karlNet.sambamanager.ldapController.commands.AddUserToGroup;
import de.karlNet.sambamanager.ldapController.commands.BaseCommand;
import de.karlNet.sambamanager.ldapController.commands.ModifyUser;
import de.karlNet.sambamanager.ldapController.commands.RemoveUserFromGroup;
import de.karlNet.sambamanager.ldapModel.ITypeCheckerCallback;
import de.karlNet.sambamanager.ldapModel.LdapGroup;
import de.karlNet.sambamanager.ldapModel.LdapObject;
import de.karlNet.sambamanager.ldapModel.dto.LdapUserCreationDTO;

@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ModifyUserMacro extends BaseCommand{
	@Autowired
	private LdapMemberOfTree memberOfTree;
	@Autowired
	private AddUserToGroup addUserToGroup;
	@Autowired
	private RemoveUserFromGroup removeUserFromGroup;
	@Autowired
	private ModifyUser modifyUser;

	public void updateUser(final LdapUserCreationDTO userCreationDTO)
			throws NamingException, UnsupportedEncodingException {
		final ArrayList<LdapObject> toRemove = new ArrayList<LdapObject>();
		for (final LdapObject ldapGroup : this.memberOfTree
				.getChildrenOfDN(userCreationDTO.getLdapUser().getDn())) {
			ldapGroup.isType(new ITypeCheckerCallback() {
				@Override
				public void isGroup(LdapGroup group) {
					toRemove.add(ldapGroup);
				}
			});
		}
		toRemove.removeAll(userCreationDTO.getMemberShips());
		userCreationDTO.getMemberShips().removeAll(this.memberOfTree
				.getChildrenOfDN(userCreationDTO.getLdapUser().getDn()));
		for (final LdapObject ldapGroup : toRemove) {
			ldapGroup.isType(new ITypeCheckerCallback() {
				@Override
				public void isGroup(LdapGroup group) {
					removeUserFromGroup.removeUserFromGroupItself(group,
							userCreationDTO.getLdapUser());
				}
			});
		}
		this.addUserToGroup.addUserToGroupItself(userCreationDTO);
		this.modifyUser.modifyUserItSelf(userCreationDTO.getLdapUser());
		this.resetTrees();
	}
}
